﻿using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Data.Odbc;
using System.Web;

namespace app.scrum
{
    public class JsonHelper
    {
        //---------------------------------Object to Json
        public static string getJson(DbDataReader reader, string objType)
        {
            string json = ",root:[";
            int rowCount = 0;
            int fieldCount = reader.FieldCount;
            while (reader.Read())
            {
                json += "{";
                for (int i = 0; i < fieldCount; i++)
                {
                    String fName = reader.GetName(i);
                    object col = reader.GetValue(i);
                    json += fName + ":'" + col + "',";
                }
                //json = json.Substring(0, json.Length - 1);
                json += ScrumField.fieldName_ObjectType + ":'" + objType + "'";
                json += "},";
                rowCount++;
            }
            if (rowCount > 0)
            {
                json = json.Substring(0, json.Length - 1);
            }
            json += "]}";
            json = "{total:" + rowCount + json;
            return json;
        }

        public static string getJson(DataTable table)
        {
            string json = ",root:[";
            int rowCount = table.Rows.Count;
            int fieldCount = table.Columns.Count;
            for (int i = 0; i < rowCount; i++)
            {
                json += "{";
                for (int j = 0; j < fieldCount; j++)
                {
                    String fName = table.Columns[j].ColumnName;
                    object col = table.Rows[i][fName];
                    json += fName + ":'" + col + "',";
                }
                //json = json.Substring(0, json.Length - 1);
                json +=  ScrumField.fieldName_ObjectType + ":'" + table.TableName + "'";
                json += "},";
            }
            if (rowCount > 0)
            {
                json = json.Substring(0, json.Length - 1);
            }
            json += "]}";
            json = "{total:" + rowCount + json;
            return json;
        }

        public static string getJson(ArrayList objList)
        {
            string json = ",root:[";
            int rowCount = objList.Count;
            foreach (Object obj in objList)
            {
                if (obj is ScrumObject)
                {
                    ScrumObject sObj = (ScrumObject)obj;
                    json += getJson(sObj) + ",";
                }
                else if (obj is String)
                {

                }
            }
            if (rowCount > 0)
            {
                json = json.Substring(0, json.Length - 1);
            }
            json += "]}";
            json = "{total:" + rowCount + json;
            return json;
        }

        public static string getJson(ScrumObject sObj)
        {
            string json = "{";
            foreach (ScrumField sField in sObj.fieldList)
            {
                json += getJson(sField) + ",";
            }
            bool hasChild = sObj.childList.Count > 0;
            if (hasChild)
            {
                json += "children:[";
                foreach (ScrumObject child in sObj.childList)
                {
                    json += getJson(child) + ",";
                }
                json = json.Substring(0, json.Length - 1);
                json += "]";
            }
            else
            {
                json = json.Substring(0, json.Length - 1);
            }
            json += "}";
            return json;
        }

        public static string getJson(ScrumField sField)
        {
            string json = sField.name.ToLower() + ":";
            if (ScrumField.typeOptions_Lookup != sField.typeName)
            {
                json += "'" + sField.value + "'";
            }
            else
            {
                json += "{value:'" + sField.value + "', display:'" + sField.display + "', candidateValue:" + sField.candidateValues + "}";
            }
            return json;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonRecPart">[{},{}....]</param>
        /// <returns>[[Id,Name],[Id,Name]]</returns>
        public static string jsonRecPart2Array(string jsonRecPart)
        {
            string jsonTwoDimArray = "[";            
            string[] recordArray = getJsonRecordArrayFromJson(jsonRecPart);
            foreach (string record in recordArray)
            {
                string[] propertyArray = getJsonPropertyArrayFromJson(record);
                jsonTwoDimArray += "[";
                foreach (string property in propertyArray)
                {
                    string[] keyValue = getJsonKeyValueFromJson(property);
                    jsonTwoDimArray += keyValue[1] + ",";
                }
                jsonTwoDimArray = jsonTwoDimArray.Substring(0, jsonTwoDimArray.Length - 1);
                jsonTwoDimArray += "],";
            }
            jsonTwoDimArray = jsonTwoDimArray.Substring(0, jsonTwoDimArray.Length - 1);
            jsonTwoDimArray += "]";
            return jsonTwoDimArray;
        }
        //[[Id,Name],[Id,Name]]
        public static string stringList2Array(ArrayList stringList)
        {
            string jsonTwoDimArray = "[";
            foreach (string str in stringList)
            {
                jsonTwoDimArray += "['" + str + "','" + str + "'],";
            }
            jsonTwoDimArray = jsonTwoDimArray.Substring(0, jsonTwoDimArray.Length - 1);
            jsonTwoDimArray += "]";
            return jsonTwoDimArray;
        }

        //---------------------------------Json to Object

        public static ArrayList getScrumObjectList(string json)
        {
            ArrayList sObjList = new ArrayList();
            if (Util.isEmpty(json))
            {
                return sObjList;
            }
            if (json.IndexOf("[") < 0)
            {
                ScrumObject sObj = getScrumObject(json);
                if (sObj.fieldList.Count > 0)
                {
                    sObjList.Add(sObj);
                }
            }
            else
            {
                json = getJsonRecordPartFromJson(json);
                string[] recordArray = getJsonRecordArrayFromJson(json);
                foreach (string record in recordArray)
                {
                    ScrumObject sObj = new ScrumObject();
                    string[] propertyArray = getJsonPropertyArrayFromJson(record);
                    foreach (string property in propertyArray)
                    {
                        ScrumField sField = new ScrumField();
                        string[] keyValue = getJsonKeyValueFromJson(property);
                        sField.name = getJsonKeyOrValueFromJson(keyValue[0]);
                        sField.value = getJsonKeyOrValueFromJson(keyValue[1]);
                        sObj.fieldList.Add(sField);
                        sObj.fieldMap.Add(sField.name, sField);
                    }
                    sObjList.Add(sObj);
                }
            }
            return sObjList;
        }

        public static ScrumObject getScrumObject(string json)
        {
            ScrumObject sObj = new ScrumObject();
            if (Util.isEmpty(json))
            {
                return sObj;
            }
            string[] propertyArray = getJsonPropertyArrayFromJson(json);
            foreach (string property in propertyArray)
            {
                ScrumField sField = new ScrumField();
                string[] keyValue = getJsonKeyValueFromJson(property);
                sField.name = getJsonKeyOrValueFromJson(keyValue[0]);
                sField.value = getJsonKeyOrValueFromJson(keyValue[1]);
                sObj.fieldList.Add(sField);
                sObj.fieldMap.Add(sField.name, sField);
            }
            return sObj;
        }

        //---------------------------------Common

        //without "root:"
        public static string getJsonRootPartValueFromJson(string json)
        {
            string recordPart = null;
            int start = json.IndexOf("[");
            int end = json.LastIndexOf("]");
            recordPart = json.Substring(start, end - start + 1);
            return recordPart;
        }

        //without "root:", without "[" and "]"
        public static string getJsonRecordPartFromJson(string json)
        {
            string rootPart = getJsonRootPartValueFromJson(json);
            string recordPart = "";
            if (!Util.isEmpty(rootPart))
            {
                recordPart = rootPart.Substring(1, rootPart.Length - 2);
            }
            return recordPart;
        }

        private static string[] getJsonRecordArrayFromJson(string jsonRecPart)
        {
            string[] recordArray = jsonRecPart.Split(new string[] { "}" }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < recordArray.Length; i++ )
            {
                if (recordArray[i].StartsWith("{") || recordArray[i].StartsWith(",{"))
                {
                    int index = recordArray[i].IndexOf("{");
                    recordArray[i] = recordArray[i].Substring(index + 1, (recordArray[i].Length - index - 1));
                }
            }
            return recordArray;
        }

        private static string[] getJsonPropertyArrayFromJson(string record)
        {
            if (record.StartsWith("{"))
            {
                record = record.Substring(1);
            }
            if (record.EndsWith("}"))
            {
                record = record.Substring(0, record.Length - 1);
            }
            return record.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string[] getJsonKeyValueFromJson(string property)
        {
            return property.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string getJsonKeyOrValueFromJson(string keyOrValue)
        {
            if (String.Equals(keyOrValue, "null"))
            {
                keyOrValue = null;
            }
            else
            {
                if (keyOrValue.StartsWith("\""))
                {
                    keyOrValue = keyOrValue.Substring(1);
                }
                if (keyOrValue.EndsWith("\""))
                {
                    keyOrValue = keyOrValue.Substring(0, keyOrValue.Length - 1);
                }
            }
            return keyOrValue;
        }

    }
}